package com.efeichong.oss;

import com.google.common.io.Files;
import lombok.Cleanup;
import lombok.NonNull;
import lombok.SneakyThrows;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Nullable;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author lxk
 * @date 2020/11/5
 * @description 本地oss操作
 */
public class LocalOssService extends AbstractOssService implements OssService{

    public LocalOssService(@NonNull OssConfigLocal config) {
        super(config);
    }

    @SneakyThrows
    @Override
    public String upload(MultipartFile file, String bucketName, String folderName, @NonNull String suffix) {
        String uuid = UUIDUtils.getId();
        if (!suffix.startsWith(".")) {
            suffix = "." + suffix;
        }
        String newFileName = uuid + suffix;
        //实际路径
        StringBuilder originalBuilder = new StringBuilder(baseDir);
        if (StringUtils.isNotBlank(folderName)) {
            originalBuilder.append(File.separator).append(folderName);
        }
        originalBuilder.append(File.separator).append(newFileName);
        //显示路径  将根路径替换为 {@linkplain RESOURCE}
        StringBuilder viewBuilder = new StringBuilder(viewUrlPrefix);
        if (StringUtils.isNotBlank(folderName)) {
            viewBuilder.append("/").append(folderName);
        }
        viewBuilder.append("/").append(newFileName);

        File desc = new File(originalBuilder.toString());
        if (!desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }
        if (!desc.exists()) {
            desc.createNewFile();
        }
        file.transferTo(desc);
        return getViewUrl(viewBuilder.toString());
    }

    @Override
    public List<String> upload(MultipartFile[] files, String bucketName, final String folderName, @NonNull String suffix) {
        List<String> urls = Arrays.stream(files).map(file -> upload(file, bucketName, folderName, suffix)).collect(Collectors.toList());
        return urls;
    }

    @SneakyThrows
    @Override
    public String upload(byte[] bytes, String bucketName, String folderName, String suffix) {
        String uuid = UUIDUtils.getId();
        if (!suffix.startsWith(".")) {
            suffix = "." + suffix;
        }
        String newFileName = uuid + suffix;
        //实际路径
        StringBuilder originalBuilder = new StringBuilder(baseDir);
        if (StringUtils.isNotBlank(folderName)) {
            originalBuilder.append(File.separator).append(folderName);
        }
        originalBuilder.append(File.separator).append(newFileName);
        //显示路径  将根路径替换为 {@linkplain RESOURCE}
        StringBuilder viewBuilder = new StringBuilder(viewUrlPrefix);
        if (StringUtils.isNotBlank(folderName)) {
            viewBuilder.append("/").append(folderName);
        }
        viewBuilder.append("/").append(newFileName);

        File desc = new File(originalBuilder.toString());
        if (!desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }
        if (!desc.exists()) {
            desc.createNewFile();
        }
        Files.write(bytes, desc);
        return getViewUrl(viewBuilder.toString());
    }

    @SneakyThrows
    @Override
    public byte[] download(String url) {
        File file = new File(getOriginPath(url));
        @Cleanup FileInputStream inputStream = new FileInputStream(file);
        return IoUtils.inputStreamToByte(inputStream);
    }

    @SneakyThrows
    @Override
    public ZipOutputStream batchDownload(OutputStream outputStream, List<String> urls) {
        @Cleanup ZipOutputStream zos = new ZipOutputStream(outputStream);
        urls.forEach(FunctionWithException.wrapper(url -> {
            File file = new File(getOriginPath(url));
            @Cleanup FileInputStream inputStream = new FileInputStream(file);
            byte[] buf = new byte[1024];
            zos.putNextEntry(new ZipEntry(url.substring(url.lastIndexOf("/") + 1)));
            int len;
            while ((len = inputStream.read(buf)) != -1) {
                zos.write(buf, 0, len);
            }
            zos.closeEntry();
        }));
        return zos;
    }

    @SneakyThrows
    @Override
    public void delete(String url) {
        File file = new File(getOriginPath(url));
        if (file.exists()) {
            file.delete();
        }
    }

    @Override
    public void batchDelete(List<String> urls) {
        urls.stream().forEach(url -> delete(url));
    }



    /**
     * 获取返回给前端的url路径
     *
     * @param path
     * @return
     */
    private String getViewUrl(String path) {
        return showDomainUrl + "/" + path;
    }

    /**
     * 获取文件实际路径
     *
     * @param url
     * @return
     */
    private String getOriginPath(String url) {
        return url.substring(url.indexOf(viewUrlPrefix)).replace(viewUrlPrefix, baseDir);
    }

}
